#include <gtest/gtest.h>
#include "position_manager.h"

using namespace hft;

class PositionManagerTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 设置测试环境
        position_manager_ = std::make_unique<PositionManager>();
    }

    std::unique_ptr<PositionManager> position_manager_;
};

// 测试持仓创建和更新
TEST_F(PositionManagerTest, CreateAndUpdatePosition) {
    // 创建一个买入成交
    Trade trade;
    trade.trade_id = "T1";
    trade.order_id = "O1";
    trade.symbol = "IF2403";
    trade.side = OrderSide::Buy;
    trade.price = 7500.0;
    trade.volume = 10;
    trade.account = "test_account";
    trade.strategy_id = "test_strategy";

    position_manager_->onTrade(trade);

    // 验证持仓是否正确创建
    Position* position = position_manager_->getPosition("IF2403", "test_account", "test_strategy");
    ASSERT_NE(position, nullptr);
    EXPECT_EQ(position->symbol, "IF2403");
    EXPECT_EQ(position->account, "test_account");
    EXPECT_EQ(position->strategy_id, "test_strategy");
    EXPECT_EQ(position->side, PositionSide::Long);
    EXPECT_EQ(position->volume, 10);
    EXPECT_EQ(position->avg_price, 7500.0);
    EXPECT_EQ(position->today_volume, 10);
    EXPECT_EQ(position->today_avg_price, 7500.0);
    EXPECT_EQ(position->history_volume, 0);

    // 再次买入，测试持仓更新
    trade.trade_id = "T2";
    trade.price = 7600.0;
    trade.volume = 5;
    position_manager_->onTrade(trade);

    position = position_manager_->getPosition("IF2403", "test_account", "test_strategy");
    ASSERT_NE(position, nullptr);
    EXPECT_EQ(position->volume, 15);
    // 平均价格应该是 (7500*10 + 7600*5) / 15 = 7533.33
    EXPECT_NEAR(position->avg_price, 7533.33, 0.01);
    EXPECT_EQ(position->today_volume, 15);
    EXPECT_NEAR(position->today_avg_price, 7533.33, 0.01);

    // 卖出一部分，测试持仓减少
    trade.trade_id = "T3";
    trade.side = OrderSide::Sell;
    trade.price = 7700.0;
    trade.volume = 8;
    position_manager_->onTrade(trade);

    position = position_manager_->getPosition("IF2403", "test_account", "test_strategy");
    ASSERT_NE(position, nullptr);
    EXPECT_EQ(position->volume, 7);
    EXPECT_NEAR(position->avg_price, 7533.33, 0.01); // 平均价格不变
    EXPECT_EQ(position->today_volume, 7);
    EXPECT_NEAR(position->today_avg_price, 7533.33, 0.01);
    // 已实现盈亏应该是 (7700 - 7533.33) * 8 = 1333.36
    EXPECT_NEAR(position->realized_pnl, 1333.36, 0.01);
}

// 测试最新价格更新和未实现盈亏计算
TEST_F(PositionManagerTest, UpdateLastPriceAndUnrealizedPnL) {
    // 创建一个买入成交
    Trade trade;
    trade.trade_id = "T1";
    trade.order_id = "O1";
    trade.symbol = "IF2403";
    trade.side = OrderSide::Buy;
    trade.price = 7500.0;
    trade.volume = 10;
    trade.account = "test_account";
    trade.strategy_id = "test_strategy";

    position_manager_->onTrade(trade);

    // 更新最新价格
    position_manager_->updateLastPrice("IF2403", 7600.0);

    // 验证未实现盈亏
    Position* position = position_manager_->getPosition("IF2403", "test_account", "test_strategy");
    ASSERT_NE(position, nullptr);
    EXPECT_EQ(position->last_price, 7600.0);
    // 未实现盈亏应该是 (7600 - 7500) * 10 = 1000
    EXPECT_NEAR(position->unrealized_pnl, 1000.0, 0.01);

    // 更新最新价格为亏损
    position_manager_->updateLastPrice("IF2403", 7400.0);

    position = position_manager_->getPosition("IF2403", "test_account", "test_strategy");
    ASSERT_NE(position, nullptr);
    EXPECT_EQ(position->last_price, 7400.0);
    // 未实现盈亏应该是 (7400 - 7500) * 10 = -1000
    EXPECT_NEAR(position->unrealized_pnl, -1000.0, 0.01);
}

// 测试多个持仓的管理
TEST_F(PositionManagerTest, MultiplePositions) {
    // 创建第一个持仓
    Trade trade1;
    trade1.trade_id = "T1";
    trade1.order_id = "O1";
    trade1.symbol = "IF2403";
    trade1.side = OrderSide::Buy;
    trade1.price = 7500.0;
    trade1.volume = 10;
    trade1.account = "account1";
    trade1.strategy_id = "strategy1";

    position_manager_->onTrade(trade1);

    // 创建第二个持仓
    Trade trade2;
    trade2.trade_id = "T2";
    trade2.order_id = "O2";
    trade2.symbol = "IC2403";
    trade2.side = OrderSide::Sell;
    trade2.price = 8500.0;
    trade2.volume = 5;
    trade2.account = "account1";
    trade2.strategy_id = "strategy2";

    position_manager_->onTrade(trade2);

    // 创建第三个持仓
    Trade trade3;
    trade3.trade_id = "T3";
    trade3.order_id = "O3";
    trade3.symbol = "IF2403";
    trade3.side = OrderSide::Buy;
    trade3.price = 7600.0;
    trade3.volume = 8;
    trade3.account = "account2";
    trade3.strategy_id = "strategy1";

    position_manager_->onTrade(trade3);

    // 测试按账户查询
    auto account1_positions = position_manager_->getAccountPositions("account1");
    EXPECT_EQ(account1_positions.size(), 2);

    // 测试按策略查询
    auto strategy1_positions = position_manager_->getStrategyPositions("strategy1");
    EXPECT_EQ(strategy1_positions.size(), 2);

    // 测试按合约查询
    auto if2403_positions = position_manager_->getSymbolPositions("IF2403");
    EXPECT_EQ(if2403_positions.size(), 2);

    // 验证所有持仓
    const auto& all_positions = position_manager_->getAllPositions();
    EXPECT_EQ(all_positions.size(), 3);
}

// 测试日终结算
TEST_F(PositionManagerTest, SettlePositions) {
    // 创建一个买入成交
    Trade trade;
    trade.trade_id = "T1";
    trade.order_id = "O1";
    trade.symbol = "IF2403";
    trade.side = OrderSide::Buy;
    trade.price = 7500.0;
    trade.volume = 10;
    trade.account = "test_account";
    trade.strategy_id = "test_strategy";

    position_manager_->onTrade(trade);

    // 验证今仓
    Position* position = position_manager_->getPosition("IF2403", "test_account", "test_strategy");
    ASSERT_NE(position, nullptr);
    EXPECT_EQ(position->today_volume, 10);
    EXPECT_EQ(position->history_volume, 0);

    // 执行日终结算
    position_manager_->settle();

    // 验证今仓转为昨仓
    position = position_manager_->getPosition("IF2403", "test_account", "test_strategy");
    ASSERT_NE(position, nullptr);
    EXPECT_EQ(position->today_volume, 0);
    EXPECT_EQ(position->history_volume, 10);
    EXPECT_NEAR(position->history_avg_price, 7500.0, 0.01);
    EXPECT_EQ(position->realized_pnl, 0.0); // 已实现盈亏应该被清零
}

// 测试保证金更新
TEST_F(PositionManagerTest, UpdateMargin) {
    // 创建一个买入成交
    Trade trade;
    trade.trade_id = "T1";
    trade.order_id = "O1";
    trade.symbol = "IF2403";
    trade.side = OrderSide::Buy;
    trade.price = 7500.0;
    trade.volume = 10;
    trade.account = "test_account";
    trade.strategy_id = "test_strategy";

    position_manager_->onTrade(trade);

    // 更新最新价格
    position_manager_->updateLastPrice("IF2403", 7500.0);

    // 设置保证金率
    position_manager_->updateMarginRatio("IF2403", 0.1);

    // 验证保证金
    Position* position = position_manager_->getPosition("IF2403", "test_account", "test_strategy");
    ASSERT_NE(position, nullptr);
    // 保证金应该是 7500 * 10 * 0.1 = 7500
    EXPECT_NEAR(position->margin, 7500.0, 0.01);
    // 杠杆率应该是 10
    EXPECT_NEAR(position->leverage, 10.0, 0.01);

    // 更新保证金率
    position_manager_->updateMarginRatio("IF2403", 0.2);

    position = position_manager_->getPosition("IF2403", "test_account", "test_strategy");
    ASSERT_NE(position, nullptr);
    // 保证金应该是 7500 * 10 * 0.2 = 15000
    EXPECT_NEAR(position->margin, 15000.0, 0.01);
    // 杠杆率应该是 5
    EXPECT_NEAR(position->leverage, 5.0, 0.01);
}